package com.example.exam.filter;

import com.example.exam.constant.LoginConstant;
import com.example.exam.constant.TimeConstant;
import com.example.exam.service.RedisService;
import com.example.exam.utils.JsonUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhozixiong
 * @date 2023/03/08
 *
 * 登录过滤器
 */
public class LoginFilter implements HandlerInterceptor {

    private RedisService redisService;

    public LoginFilter(RedisService redisService) {
        this.redisService = redisService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取url
        String url = request.getRequestURI();
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        //判断是否为登录请求
        if(url.equals(LoginConstant.LOGIN_URL)) {
            if(token != null) {
                output(response, 2003, "已登录", null);
                return false;
            }else {
                return true;
            }
        }
        //当前时间
        long time = System.currentTimeMillis();
        //开始时间
        Object startObject = redisService.getObject(TimeConstant.START_TIME);
        //结束时间
        Object endObject = redisService.getObject(TimeConstant.END_TIME);
        //判断是否到达考试时间
        if(startObject != null && (long) startObject > time) {
            Map<String, Object> map = new HashMap<>(2);
            //考试开始时间
            map.put(TimeConstant.START_TIME, startObject);
            //当前时间
            map.put("currentTime", time);
            output(response, 2010, "考试未开始", map);
            return false;
        }else if(endObject != null && (long) endObject < time) {
            output(response, 2011, "考试已结束", null);
            return false;
        }
        if(token != null) {
            //验证令牌的真伪
            String sid = (String) redisService.getObject(LoginConstant.TOKEN_PREFIX + token);
            if(sid != null) {
                request.setAttribute(LoginConstant.USER_ID, sid);
                return true;
            }else {
                output(response, 2002, "登录已过期", null);
                return false;
            }
        }else {
            output(response, 2001, "未登录", null);
            return false;
        }
    }

    /**
     * @param code 状态码
     * @param msg 错误信息
     * @param time 响应信息
     */
    private void output(HttpServletResponse response, int code, String msg, Map<String, Object> time) throws IOException {
        Map<String, Object> map = new HashMap<>(3);
        //错误状态码
        map.put("code", code);
        //错误信息
        map.put("msg", msg);
        if(time != null) {
            map.put("time", time);
        }
        String json = JsonUtil.toString(map);
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().print(json);
    }
}
